
#[derive(PartialEq, Debug, Clone, Copy)]
pub struct Position {
    pub  row: i64,
    pub col: i64,
}

impl Position {
    pub fn default() -> Self {
        Self { row: 0, col: 0 }
    }

    pub fn new(row: i64, col: i64) -> Self {
        Self { row, col }
    }
}

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Pipe {
    Vertical,
    Horizontal,
    NorthEast,
    NorthWest,
    SouthWest,
    SouthEast,
    Ground,
}

impl Pipe {
    pub fn next(&self, position: &Position) -> Vec<Position> {
        let mut positions = Vec::new();

        match *self {
            Pipe::Vertical   => {
                positions.push(Position::new(position.row + 1, position.col));
                positions.push(Position::new(position.row - 1, position.col));
            }
            Pipe::Horizontal => {
                positions.push(Position::new(position.row, position.col + 1));
                positions.push(Position::new(position.row, position.col - 1));
            }
            Pipe::NorthEast  => {
                positions.push(Position::new(position.row, position.col + 1));
                positions.push(Position::new(position.row - 1, position.col));
            }
            Pipe::NorthWest  => {
                positions.push(Position::new(position.row, position.col - 1));
                positions.push(Position::new(position.row - 1, position.col));
            }
            Pipe::SouthWest  => {
                positions.push(Position::new(position.row, position.col - 1));
                positions.push(Position::new(position.row + 1, position.col));
            }
            Pipe::SouthEast  => {
                positions.push(Position::new(position.row, position.col + 1));
                positions.push(Position::new(position.row + 1, position.col));
            }
            Pipe::Ground     => {}
        }
        
        positions
    }
}

pub fn make_pipe(token: char) -> Pipe {
    match token {
        '|' => return Pipe::Vertical,
        '-' => return Pipe::Horizontal,
        'L' => return Pipe::NorthEast,
        'J' => return Pipe::NorthWest,
        '7' => return Pipe::SouthWest,
        'F' => return Pipe::SouthEast,
        '.' => return Pipe::Ground,
        _   => panic!("{}", token),
    }
}
